﻿using Castle.DynamicProxy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace JGSY.SerialCommunication.UpperComputer.Core.AOP.ThirdPartyLibrary.Proxy
{
    /// <summary>
    /// 代理
    /// </summary>
    public static class ProxyFactoryCastleDynamicProxy
    {
        private static readonly ProxyGenerator generator = new ProxyGenerator();

        //public static T CreateProxy<T>(T target) where T : class
        //{
        //    //一个
        //    //var interceptors = target.GetType()
        //    //    .GetMethods(BindingFlags.Public | BindingFlags.Instance)
        //    //    .SelectMany(m => m.GetCustomAttributes<LogAspectCastleDynamicProxyAttribute>())
        //    //    .Cast<IInterceptor>()
        //    //    .ToArray();

        //    //return generator.CreateInterfaceProxyWithTargetInterface(target, interceptors);

        //    try
        //    {
        //        // 获取所有方法上的拦截器特性
        //        var interceptors = target.GetType()
        //            .GetMethods(BindingFlags.Public | BindingFlags.Instance)
        //            .SelectMany(m => m.GetCustomAttributes(true)
        //                .OfType<IInterceptor>())
        //            .Distinct()
        //            .ToArray();

        //        return generator.CreateInterfaceProxyWithTargetInterface(target, interceptors);
        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine($"创建代理时发生异常: {ex.Message}");
        //        throw;
        //    } 
        //}
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="target"></param>
        /// <returns></returns>
        public static T CreateProxy<T>(T target) where T : class
        {
            try
            {
                // 获取所有方法上的拦截器特性
                var interceptors = target.GetType()
                    .GetMethods(BindingFlags.Public | BindingFlags.Instance)
                    .SelectMany(m => m.GetCustomAttributes(true)
                        .OfType<IInterceptor>())
                    .Distinct()
                    .ToArray();

                // 按特性应用顺序排序拦截器
                Array.Sort(interceptors, (x, y) => {
                    var xAttr = x as Attribute;
                    var yAttr = y as Attribute;
                    if (xAttr == null || yAttr == null) return 0;

                    var xOrder = GetAttributeOrder(xAttr);
                    var yOrder = GetAttributeOrder(yAttr);
                    return xOrder - yOrder;
                });

                return generator.CreateInterfaceProxyWithTargetInterface(target, interceptors);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"创建代理时发生异常: {ex.Message}");
                throw;
            }
        }

        private static int GetAttributeOrder(Attribute attribute)
        {
            // 定义拦截器执行顺序
            if (attribute is LogCastleDynamicProxyAttribute) return 1;
            if (attribute is ExceptionCastleDynamicProxyAttribute) return 2;
            return 0;
        }
    }
}
